/**
 * 
 */
package co.fitstart.admin.service.impl;

import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.core.persistence.annotation.Dynamic;
import com.demo2do.core.support.Page;

import co.fitstart.admin.dao.ProductDao;
import co.fitstart.admin.dao.ProductDaoSupport;
import co.fitstart.admin.entity.security.Login;
import co.fitstart.admin.service.ProductService;
import co.fitstart.entity.course.Course;
import co.fitstart.entity.course.CourseType;
import co.fitstart.entity.course.CourseUnit;
import co.fitstart.entity.finance.InventoryExportRecord;
import co.fitstart.entity.product.Product;
import co.fitstart.entity.product.ProductTag;
import co.fitstart.entity.product.ProductType;
import co.fitstart.entity.product.Status;
import co.fitstart.entity.product.Tag;

/**
 * @author downpour
 *
 */
@Service("productService")
public class ProductServiceImpl extends DataServiceImpl<Product> implements ProductService {
    
    @Autowired
    private ProductDaoSupport productDaoSupport;
    
    @Dynamic
    private ProductDao productDao;
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.ProductService#list(boolean, com.demo2do.core.support.Page)
     */
    public List<Product> list(boolean export, Page page) {
        List<Product> result = productDao.list(export, page.getBeginIndex(), page.getMaxResultRecords());
        page.calculate(result.size());
        return result.size() > page.getEveryPage() ? result.subList(0, page.getEveryPage()) : result;
    }

    /* (non-Javadoc)
     * @see co.fitstart.admin.service.ecommerce.ProductService#list(co.fitstart.common.entity.ecommerce.product.ProductType, com.demo2do.core.web.resolver.Page)
     */
    public List<Product> list(ProductType type, Page page) {
        List<Product> result = productDao.list(type, page.getBeginIndex(), page.getMaxResultRecords());
        page.calculate(result.size());
        return result.size() > page.getEveryPage() ? result.subList(0, page.getEveryPage()) : result;
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.ProductService#listUnexportProduct()
     */
    public List<Product> listUnexportProduct() {
        return productDao.listUnExportProduct();
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.ecommerce.ProductService#edit(co.fitstart.common.entity.ecommerce.product.Product, java.util.List)
     */
    public void edit(Product product, List<String> tags) {
        
        //Step1 update product with changed product tag
        genericDaoSupport.update(product.editWeight(tags));
        
        //Step2 check tag deletion
        productDaoSupport.deleteProductTags(product, tags);
            
        //Step3 add tag which is new to this product
        if(CollectionUtils.isNotEmpty(tags)) {
            for(String tag : tags) {
                if(!product.getTags().containsKey(tag)) {
                    ProductTag productTag = new ProductTag(product, Tag.aliasOf(tag));
                    genericDaoSupport.save(productTag);
                }
            }
        }
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.ecommerce.ProductService#stick(co.fitstart.common.entity.ecommerce.product.Product, java.lang.String)
     */
    public void stick(Product product, ProductType type) {
        
        List<Product> sticks = productDao.list(type);
        
        if(sticks.isEmpty()) {
            
            genericDaoSupport.update(product.stick(100));
            
        } else {
            
            Product last = sticks.get(sticks.size() -1);
            genericDaoSupport.update(product.stick(last.getWeight()));
            
        }
        
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.ecommerce.ProductService#unStick(co.fitstart.common.entity.ecommerce.product.Product, java.lang.String)
     */
    public void unStick(Product product, ProductType type) {
        
        genericDaoSupport.update(product.unstick());
        
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.ecommerce.ProductService#loadLatestProduct(co.fitstart.common.entity.course.Course)
     */
    public Product loadLatestProduct(Course course) {
        return productDao.loadLatestProduct(course);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.ecommerce.ProductService#create(co.fitstart.common.entity.ecommerce.product.Product)
     */
    public Product create(Product latestProduct) {
        Product product = new Product(latestProduct);
        genericDaoSupport.save(product.initialize());
        
        return product;
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.ProductService#exportInventory(java.util.List, co.fitstart.admin.entity.security.Login)
     */
    public void exportInventory(List<Long> productIds, Login login) {
        // update product's export first
        productDao.exportInventories(productIds);
        
        // create inventory export record
        InventoryExportRecord record = new InventoryExportRecord(productIds.size(), login.getId());
        genericDaoSupport.save(record);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.ProductService#listExportRecord(com.demo2do.core.support.Page)
     */
    public List<InventoryExportRecord> listExportRecord(Page page) {
        List<InventoryExportRecord> result = productDao.listExportRecord(page.getBeginIndex(), page.getMaxResultRecords());
        
        page.calculate(result.size());
        return result.size() > page.getEveryPage() ? result.subList(0, page.getEveryPage()) : result;
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.ProductService#listGive()
     */
    public List<Product> listGive() {
        return productDao.listGive(Status.ONLINE);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.ProductService#listExperience()
     */
    public List<Product> listExperience() {
    	return productDao.listExperience(Status.ONLINE);
    }

    public List<Product> ifExist(int hours, String name) {
        return productDao.ifExist(hours, name);
    }
    public List<Product> ifExist( String name) {
        return productDao.ifExist( name);
    }

    public Product getProduct(int hours){
        return productDao.getProduct(hours);
    }

    public Product getProduct(String name){
        return productDao.getProduct(name);
    }
    public Product getProduct(int hours, String name){
        return productDao.getProduct(hours,name);
    }
    
    public Product getProduct(CourseUnit courseUnit, CourseType courseType) {
        return productDao.getProduct(courseType, courseUnit);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.ProductService#getProduct(co.fitstart.entity.course.CourseUnit, int)
     */
    public Product getProduct(CourseUnit courseUnit, int hours) {
        return productDao.getProduct(hours, courseUnit);
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.ProductService#deletedProduct(boolean)
     */
    public void deletedProduct(boolean deleted,Long productId) {
    	
    	Product product = productDao.load(productId);
    	
    	product.deleteProduct(deleted);
    	
    	genericDaoSupport.update(product);
		
	}
    
    
}
